package cn.sciento.farm.devicemanager.common.util;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;

/**
 * @author wumu
 * @version V1.0
 * @date 4/21/18
 * @time 4:59 PM
 */
public class SensorBase64Util {

    private static final String BASE_64_TABLE = "QBykEF/HZJ9bNMOPAhSTUVo5YIqLctujgRifDlmnWparsde+wxCz03214X678KvG+/";
    private static final String ADD = "=";

    /**
     * base64编码
     */
    public static String encode(String str, String charsetName) {
        StringBuilder base64Str = new StringBuilder();
        byte[] bytesStr;
        try {
            bytesStr = str.getBytes(charsetName);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        // 编码为二进制字符串
        StringBuilder bytesBinary = new StringBuilder(binary(bytesStr, 2));
        // 24位为一组，不够后面补0,计算出需要补充的个数
        int addCount = 0;
        while (bytesBinary.length() % 24 != 0) {
            bytesBinary.append("0");
            addCount++;
        }
        for (int i = 0; i <= bytesBinary.length() - 6; i += 6) {
            // 二进制转十进制
            int index = Integer.parseInt(bytesBinary.substring(i, i + 6), 2);
            // 如果是有补位的6个0组成，则转换为'='
            if (index == 0 && i >= bytesBinary.length() - addCount) {
                base64Str.append(ADD);
            } else {
                base64Str.append(BASE_64_TABLE.charAt(index));
            }
        }
        return base64Str.toString();
    }

    /**
     * base64解码
     */
    public static String decode(String base64str, String charsetName) {
        StringBuilder base64Binarys = new StringBuilder();
        for (int i = 0; i < base64str.length(); i++) {
            char s = base64str.charAt(i);
            if (s != '=') {
                // 十进制转二进制
                StringBuilder binary = new StringBuilder(Integer.toBinaryString(BASE_64_TABLE.indexOf(s)));
                // 不够六位进行补位
                while (binary.length() != 6) {
                    binary.insert(0, "0");
                }
                base64Binarys.append(binary);
            }
        }
        // 长度应该是8的倍数，去除后面多余的0
        base64Binarys = new StringBuilder(base64Binarys.substring(0, base64Binarys.length() - base64Binarys.length() % 8));
        byte[] bytesStr = new byte[base64Binarys.length() / 8];
        for (int bytesIndex = 0; bytesIndex < base64Binarys.length() / 8; bytesIndex++) {
            // 八位截取一次，转化为一个字节
            bytesStr[bytesIndex] = (byte) Integer.parseInt(base64Binarys.substring(bytesIndex * 8, bytesIndex * 8 + 8), 2);
        }
        try {
            return new String(bytesStr, charsetName);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 字节数组转自定义进制字符串
     */
    private static String binary(byte[] bytes, int radix) {
        // 转化为二进制字符串   1代表正数,如果第一个字节以0开头，转化后会省略，所以要重新补位
        StringBuilder strBytes = new StringBuilder(new BigInteger(1, bytes).toString(radix));
        while (strBytes.length() % 8 != 0) {
            strBytes.insert(0, "0");
        }
        return strBytes.toString();
    }

    public static void main(String[] args) {
        String demo = "OkY4MTc3NkZwOTQxMzE4hmpNUVRDo3t12222h";
        String base64Str = decode(demo, "utf8");
        System.out.println(base64Str);
    }


}
